package com.breeze.components.socket;

import cn.hutool.core.collection.CollUtil;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;

/**
 * 心跳检测
 *
 * @author breeze
 */
@Slf4j
public class WebSocketHeartBeatChecker {

  /**
   * 检测WebSocket的心跳时间跟现在的间隔，超过设定的值说明失去了心跳，去除并更新数据
   *
   * @param webSocketManager 检测容器
   * @param timeSpan 检查到心跳更新时间大于timeSpan毫秒就认为断开
   * @param errorTolerant 容忍没有心跳次数
   */
  public void check(WebSocketManager webSocketManager, long timeSpan, int errorTolerant) {
    // 最少容忍一次
    errorTolerant = Math.max(errorTolerant, 1);
    final long timeSpans = timeSpan * errorTolerant;
    Date now = new Date();
    List<WebSocket> toRemoves = new ArrayList<>();
    Map<String, WebSocket> socketMap = webSocketManager.localWebSocketMap();
    socketMap.forEach(
        (identifier, webSocket) -> {
          long interval = now.getTime() - webSocket.getLastHeart().getTime();
          if (interval >= timeSpans) {
            log.debug("{} 失去心跳", identifier);
            toRemoves.add(webSocket);
          }
        });
    if (CollUtil.isNotEmpty(toRemoves)) {
      toRemoves.forEach(webSocket -> socketMap.remove(webSocket.getIdentifier()));
    }
  }
}
